#!/usr/bin/env python
# -*- coding: utf-8 -*-
"""Instant window focus script.

Environment: Python 2.5 or 2.6
Licence: GPL version 2
Author: tkykhs@gmail.com
Copyright: 2009, 2010 tkykhs <tkykhs@gmail.com>

FORMAT:
$ windowfocus <query>

INTERPRETATION.

1. If <query> matches any of QUERY_TRANSLATION's key, its value becomes the
condition to be matched against each window.

2. If <query> is 'unmatched', then the program tries to capture the window that
doesn't match any of the conditions in QUERY_TRANSLATION.

3. If <query> matches none of QUERY_TRANSLATION's key or 'unmatched', then
DEFAULT_CONDITION gets used as the condition.

EXAMPLES:
$ windowfocus.py firefox
$ windowfocus.py unmatched
"""
import gtk, wnck
from itertools import ifilter

_DEBUG = False

DEFAULT_CONDITION = lambda e: e.windowtype=='normal' and e.query.lower() in e.classname.lower()
QUERY_TRANSLATION = {  ## Non-default condition for specific queries
  'firefox'     : lambda e: e.windowtype=='normal' and e.classname=='Firefox' and e.title.endswith('Mozilla Firefox'),
  'emacs'       : lambda e: e.windowtype=='normal' and e.classname=='Emacs' and e.title not in ('child', 'anzan'),
  'anzan'       : lambda e: e.windowtype=='normal' and e.classname=='Emacs' and e.title=='anzan',
  'terminal'    : lambda e: e.windowtype=='normal' and e.classname=='Gnome-terminal',
  }

def exists(predicate, seq):
  for x in ifilter(predicate, seq):
    return x
  return False
UNMATCHED_CONDITION = lambda e: \
    not exists(lambda f: f(e), QUERY_TRANSLATION.values()) and \
    not e.appname.endswith('Edge Panel') and \
    e.title not in ('Untitled window', 'x-nautilus-desktop', 'child', 'anzan')


class WindowInfo:
  def __init__(self, **entries):
    self.__dict__.update(entries)
  def __str__(self):
    args = ['%s=%s' % (k, repr(v)) for (k, v) in vars(self).items()]
    return 'WindowInfo(%s)' % ', '.join(args)

def get_windowlist():
  screen = wnck.screen_get_default()
  while gtk.events_pending():
    gtk.main_iteration()
  return screen.get_windows()

def get_condition(query):
  if query == 'unmatched':
    return UNMATCHED_CONDITION
  if query in QUERY_TRANSLATION:
    return QUERY_TRANSLATION[query]
  return DEFAULT_CONDITION


def windowfocus(query):
  window_list = get_windowlist()
  condition = get_condition(query)
  retval = False
  for window in window_list:
    e = WindowInfo(title=window.get_name(),
               classname=window.get_class_group().get_res_class(),
               appname=window.get_application().get_name(),
               windowtype=window.get_window_type().value_nick,
               query=query)
    if _DEBUG: print e
    if condition(e):
      window.activate(gtk.get_current_event_time())    ## focus
      retval = True
      break
  return retval

if __name__  == '__main__':
  import sys
  
  if len(sys.argv) != 2:
    sys.stderr.write('Usage: %s <query>\n' % sys.argv[0])
    sys.exit(1)
  
  query = sys.argv[1]
  windowfocus(query)



